/*
 * TraceValueScope.c
 *
 *  Created on: 2012/07/09
 *      Author: guanxiaoying
 */
#include <float.h>
#include "../tracedef.h"
#include "trace_cmd.h"

static VOID tr_ScpCopyFlags(TRVALUESCP * scpDst, TRVALUESCP * scpOrg) {
	scpDst->size = scpOrg->size;
	scpDst->bBit = scpOrg->bBit;
	scpDst->bSigned = scpOrg->bSigned;
	scpDst->calError = scpOrg->calError;
	scpDst->bAddress = scpOrg->bAddress;
	scpDst->bFloat = scpOrg->bFloat;
}
/* default range: value scope of "int" */
VOID Tr_ScpGetDefault(
		TRVALUESCP *pstVarScope) {
	if (pstVarScope != NULL ) {
		Tr_ScpGetMinMaxByBytes(pstVarScope, INTSIZE, TRUE, FALSE );
	}
}
/* return a invalid value-scope */
VOID Tr_ScpGetDefaultNan(TRVALUESCP *pstVarScope) {
	if (pstVarScope != NULL ) {
		Tr_ScpGetDefault(pstVarScope);
		pstVarScope->usScopeKind = SCOPEKIND_NAN;
	}
}
VOID Tr_ScpAdjustByScp(TRVALUESCP *scp, TRVALUESCP* result) {
	if (scp->usScopeKind == SCOPEKIND_VOID || scp->usScopeKind == SCOPEKIND_NAN) {
		/* do not need to calcute */
		return;
	}
	if (result->usScopeKind == SCOPEKIND_NAN) {
		/* set to NAN */
		*scp = *result;
		return;
	}
	if (scp->bFloat == result->bFloat
			&& (scp->size < result->size
					|| (scp->size == result->size
							&& scp->bSigned == result->bSigned))
			&& scp->bBit == result->bBit) {
		tr_ScpCopyFlags(scp, result);
		/* no data loss */
		return;
	}
	if (scp->bFloat && result->bFloat) {
		/* double->float or long double->float or long double->double */

		if (scp->usScopeKind == SCOPEKIND_IN) {
			tr_ScpCopyFlags(scp, result);
			/* cut maximum value */
			if (Tr_ValueLessThan(&result->max, &scp->max)
					|| Tr_ValueLessThan(&scp->min, &result->min)) {
				Tr_ValueAdjust(&scp->min, result->size, TRUE, result->bFloat);
				Tr_ValueAdjust(&scp->max, result->size, TRUE, result->bFloat);
				scp->calError = CALERROR_FLOAT_OVERFLOW;
			}
		} else {
			// SCOPEKIND_OUT
			Tr_ScpGetMinMaxByBytes(scp, scp->size, scp->bSigned, scp->bFloat);
			tr_ScpCopyFlags(scp, result);
			Tr_ValueAdjust(&scp->min, result->size, TRUE, result->bFloat);
			Tr_ValueAdjust(&scp->max, result->size, TRUE, result->bFloat);
			scp->calError = CALERROR_FLOAT_OVERFLOW;
		}
	} else if (!scp->bFloat && result->bFloat) {
		/* integer -> floating */
		if (scp->usScopeKind == SCOPEKIND_IN) {
			tr_ScpCopyFlags(scp, result);
			Tr_ValueAdjust(&scp->min, result->size, TRUE, result->bFloat);
			Tr_ValueAdjust(&scp->max, result->size, TRUE, result->bFloat);
		} else {
			// SCOPEKIND_OUT
			if (scp->bBit) {
				Tr_ScpGetMinMaxByBits(scp, scp->size, scp->bSigned);
			} else {
				Tr_ScpGetMinMaxByBytes(scp, scp->size, scp->bSigned, FALSE);
			}
			tr_ScpCopyFlags(scp, result);
			Tr_ValueAdjust(&scp->min, result->size, TRUE, result->bFloat);
			Tr_ValueAdjust(&scp->max, result->size, TRUE, result->bFloat);
		}
	} else if (scp->bFloat && !result->bFloat) {
		/* floating -> integer */
		if (scp->usScopeKind == SCOPEKIND_IN) {
			tr_ScpCopyFlags(scp, result);
			if (result->bBit) {
				Tr_ValueAdjust2Bit(&scp->min, result->size, result->bSigned);
				Tr_ValueAdjust2Bit(&scp->max, result->size, result->bSigned);
			} else {
				Tr_ValueAdjust(&scp->min, result->size, result->bSigned,
						result->bFloat);
				Tr_ValueAdjust(&scp->max, result->size, result->bSigned,
						result->bFloat);
			}
			if (!Tr_ValueIsNormal(&scp->min) || !Tr_ValueIsNormal(&scp->max)) {
				scp->min = result->min;
				scp->max = result->max;
				scp->calError = CALERROR_FLOAT_OVERFLOW;
			}
		} else {
			// SCOPEKIND_OUT
			tr_ScpCopyFlags(scp, result);
			scp->usScopeKind = SCOPEKIND_IN;
			scp->min = result->min;
			scp->max = result->max;
			scp->calError = CALERROR_FLOAT_OVERFLOW;
		}
	} else {
		/* integer -> integer */
		if (scp->bSigned == result->bSigned) {
			// signed -> signed  or unsigned -> unsigned
			if (scp->usScopeKind == SCOPEKIND_IN) {
				tr_ScpCopyFlags(scp, result);
				if (Tr_ValueLessThan(&scp->min, &result->min)
						|| Tr_ValueLessThan(&result->max, &scp->max)) {
					scp->usScopeKind = SCOPEKIND_IN;
					scp->min = result->min;
					scp->max = result->max;
				}
				// else: in the range, nothing to do
			} else {
				tr_ScpCopyFlags(scp, result);
				scp->usScopeKind = SCOPEKIND_IN;
				scp->min = result->min;
				scp->max = result->max;
			}
		} else if (!scp->bSigned && result->bSigned) {
			// unsigned -> signed
			if (result->size == scp->size && result->bBit == scp->bBit) {
				if (scp->usScopeKind == SCOPEKIND_IN) {
					if (Tr_ValueLessThan(&result->max, &scp->max)
							&& Tr_ValueLessThan(&result->max, &scp->min)) {
						scp->usScopeKind = SCOPEKIND_IN;
						if (scp->bBit) {
							Tr_ValueAdjust2Bit(&scp->min, result->size,
									result->bSigned);
							Tr_ValueAdjust2Bit(&scp->max, result->size,
									result->bSigned);
						} else {
							Tr_ValueAdjust(&scp->min, result->size,
									result->bSigned, FALSE);
							Tr_ValueAdjust(&scp->max, result->size,
									result->bSigned, FALSE);
						}
					} else if (Tr_ValueLessThan(&result->max, &scp->max)
							&& !Tr_ValueLessThan(&result->max, &scp->min)) {
						TRVALUE max = scp->min;

						scp->min = scp->max;
						scp->max = max;
						if (scp->bBit) {
							Tr_ValueAdjust2Bit(&scp->min, result->size,
									result->bSigned);
						} else {
							Tr_ValueAdjust(&scp->min, result->size,
									result->bSigned, FALSE);
						}
						scp->usScopeKind = SCOPEKIND_OUT;
					} else {
						// in the range, nothing to do
					}
					tr_ScpCopyFlags(scp, result);
				} else {
					if (Tr_ValueLessThan(&result->max, &scp->max)
							&& Tr_ValueLessThan(&result->max, &scp->min)) {
						scp->usScopeKind = SCOPEKIND_OUT;
						if (scp->bBit) {
							Tr_ValueAdjust2Bit(&scp->min, result->size,
									result->bSigned);
							Tr_ValueAdjust2Bit(&scp->max, result->size,
									result->bSigned);
						} else {
							Tr_ValueAdjust(&scp->min, result->size,
									result->bSigned, FALSE);
							Tr_ValueAdjust(&scp->max, result->size,
									result->bSigned, FALSE);
						}
					} else if (Tr_ValueLessThan(&result->max, &scp->max)
							&& !Tr_ValueLessThan(&result->max, &scp->min)) {
						TRVALUE max = scp->min;
						scp->min = scp->max;
						scp->max = max;
						if (scp->bBit) {
							Tr_ValueAdjust2Bit(&scp->min, result->size,
									result->bSigned);
						} else {
							Tr_ValueAdjust(&scp->min, result->size,
									result->bSigned, FALSE);
						}
						scp->usScopeKind = SCOPEKIND_IN;
					} else {
						// in the range, nothing to do
					}
					tr_ScpCopyFlags(scp, result);
				}
			} else {
				*scp = *result;
			}
		} else {
			// signed -> unsigned
			if (result->size == scp->size && result->bBit == scp->bBit) {
				if (scp->usScopeKind == SCOPEKIND_IN) {
					if (Tr_ValueIsNegative(&scp->min)
							&& Tr_ValueIsNegative(&scp->max)) {
						scp->usScopeKind = SCOPEKIND_IN;
						if (scp->bBit) {
							Tr_ValueAdjust2Bit(&scp->min, result->size,
									result->bSigned);
							Tr_ValueAdjust2Bit(&scp->max, result->size,
									result->bSigned);
						} else {
							Tr_ValueAdjust(&scp->min, result->size,
									result->bSigned, FALSE);
							Tr_ValueAdjust(&scp->max, result->size,
									result->bSigned, FALSE);
						}
					} else if (Tr_ValueIsNegative(&scp->min)
							&& !Tr_ValueIsNegative(&scp->max)) {
						TRVALUE min = scp->max;
						scp->max = scp->min;
						scp->min = min;
						if (scp->bBit) {
							Tr_ValueAdjust2Bit(&scp->max, result->size,
									result->bSigned);
						} else {
							Tr_ValueAdjust(&scp->max, result->size,
									result->bSigned, FALSE);
						}
						scp->usScopeKind = SCOPEKIND_OUT;
					} else {
						// in the range, nothing to do
					}
					tr_ScpCopyFlags(scp, result);
				} else {
					if (Tr_ValueIsNegative(&scp->min)
							&& Tr_ValueIsNegative(&scp->max)) {
						scp->usScopeKind = SCOPEKIND_OUT;
						if (scp->bBit) {
							Tr_ValueAdjust2Bit(&scp->min, result->size,
									result->bSigned);
							Tr_ValueAdjust2Bit(&scp->max, result->size,
									result->bSigned);
						} else {
							Tr_ValueAdjust(&scp->min, result->size,
									result->bSigned, FALSE);
							Tr_ValueAdjust(&scp->max, result->size,
									result->bSigned, FALSE);
						}
					} else if (Tr_ValueIsNegative(&scp->min)
							&& !Tr_ValueIsNegative(&scp->max)) {
						TRVALUE min = scp->max;
						scp->max = scp->min;
						scp->min = min;
						if (scp->bBit) {
							Tr_ValueAdjust2Bit(&scp->max, result->size,
									result->bSigned);
						} else {
							Tr_ValueAdjust(&scp->max, result->size,
									result->bSigned, FALSE);
						}
						scp->usScopeKind = SCOPEKIND_IN;
					} else {
						// in the range, nothing to do
					}
					tr_ScpCopyFlags(scp, result);
				}
			} else {
				*scp = *result;
			}
		}
	}
}
VOID Tr_ScpAdjustType(TRVALUESCP *scp, AST type) {
	TRVALUESCP result;
	if (scp->usScopeKind == SCOPEKIND_VOID || scp->usScopeKind == SCOPEKIND_NAN) {
		/* do not need to calcute */
		return;
	}
	Tr_ScpGetScpByType(type, &result);
	Tr_ScpAdjustByScp(scp, &result);
}
/* return a value-scope which can be saved in memory indicated by size & signed & bFloating.
 * size: bytes
 * signed: could be negative?
 * bFloating: floating? */
VOID Tr_ScpGetMinMaxByBytes(TRVALUESCP *pstVarScope, U2 size, BOOL bSigned, BOOL bFloating) {
	pstVarScope->usScopeKind = SCOPEKIND_IN;
	pstVarScope->size = size;
	pstVarScope->bBit = FALSE;
	pstVarScope->bSigned = bSigned;
	pstVarScope->calError = 0;
	pstVarScope->bAddress = FALSE;
	pstVarScope->bFloat = bFloating;
	if (bFloating) {
		if (FLOATSIZE== size ) {
			/* type float */
			Tr_ValueNewFloatMin(&pstVarScope->min);
			Tr_ValueNewFloatMax(&pstVarScope->max);
		} else if( DOUBLESIZE == size ) {
			/* type double */
			Tr_ValueNewDoubleMin(&pstVarScope->min);
			Tr_ValueNewDoubleMax(&pstVarScope->max);
		} else if( LONGDOUBLESIZE == size ) {
			/* treat type long double as double */
			Tr_ValueNewDoubleMin(&pstVarScope->min);
			Tr_ValueNewDoubleMax(&pstVarScope->max);
		} else {
			/* invalid */
			pstVarScope->usScopeKind = SCOPEKIND_NAN;
		}
	} else if( bSigned ) {
		/* as integer */
		switch( size ) {
			case 0:
			/* void */
			Tr_ValueNewZero(&pstVarScope->min, FALSE );
			Tr_ValueNewZero(&pstVarScope->max, FALSE);
			break;
			case 1:
			/* signed char */
			Tr_ValueNewS1Min(&pstVarScope->min);
			Tr_ValueNewS1Max(&pstVarScope->max);
			break;
			case 2:
			/* short */
			Tr_ValueNewS2Min(&pstVarScope->min);
			Tr_ValueNewS2Max(&pstVarScope->max);
			break;
			case 4:
			/* long */
			Tr_ValueNewS4Min(&pstVarScope->min);
			Tr_ValueNewS4Max(&pstVarScope->max);
			break;
			case 8:
			/* long long */
			Tr_ValueNewS8Min(&pstVarScope->min);
			Tr_ValueNewS8Max(&pstVarScope->max);
			break;
			default:
			/* invalid */
			pstVarScope->usScopeKind = SCOPEKIND_NAN;
			break;
		}
	} else {
		switch( size ) {
			case 0:
			/* void */
			Tr_ValueNewZero(&pstVarScope->min, FALSE );
			Tr_ValueNewZero(&pstVarScope->max, FALSE );
			break;
			case 1:
			/* unsigned char */
			Tr_ValueNewZero(&pstVarScope->min, FALSE);
			Tr_ValueNewU1Max(&pstVarScope->max);
			break;
			case 2:
			/* unsigned short */
			Tr_ValueNewZero(&pstVarScope->min, FALSE);
			Tr_ValueNewU2Max(&pstVarScope->max);
			break;
			case 4:
			/* unsigned long */
			Tr_ValueNewZero(&pstVarScope->min, FALSE);
			Tr_ValueNewU4Max(&pstVarScope->max);
			break;
			case 8:
			/* unsigned long long */
			Tr_ValueNewZero(&pstVarScope->min, FALSE);
			Tr_ValueNewU8Max(&pstVarScope->max);
			break;
			default:
			/* invalid */
			pstVarScope->usScopeKind = SCOPEKIND_NAN;
			break;
		}
	}
}
VOID Tr_ScpGetMinMaxByBits(TRVALUESCP *pstVarScope, U2 size, BOOL bSigned) {
	pstVarScope->usScopeKind = SCOPEKIND_IN;
	pstVarScope->size = size;
	pstVarScope->bBit = TRUE;
	pstVarScope->bSigned = bSigned;
	pstVarScope->calError = FALSE;
	if (size <= 0) {
		pstVarScope->usScopeKind = SCOPEKIND_NAN;
	} else if (bSigned) {
		if (size == 1) {
			pstVarScope->min.bFloating = FALSE;
			pstVarScope->min.ucValueFlag = TRVALUE_NORMAL;
			pstVarScope->min.dbValue = -1;
			pstVarScope->max.bFloating = FALSE;
			pstVarScope->max.ucValueFlag = TRVALUE_NORMAL;
			pstVarScope->max.dbValue = 0;
		} else {
			U8 value = 1;
			while (size > 1) {
				value <<= 1;
				size--;
			}
			pstVarScope->min.bFloating = FALSE;
			pstVarScope->min.ucValueFlag = TRVALUE_NORMAL;
			pstVarScope->min.dbValue = value;
			pstVarScope->min.dbValue = -pstVarScope->min.dbValue;
			pstVarScope->max.bFloating = FALSE;
			pstVarScope->max.ucValueFlag = TRVALUE_NORMAL;
			pstVarScope->max.dbValue = value - 1;
		}
	} else {
		U8 value = 1;
		pstVarScope->bSigned = FALSE;
		while (size > 0) {
			value <<= 1;
			size--;
		}
		pstVarScope->min.bFloating = FALSE;
		pstVarScope->min.ucValueFlag = TRVALUE_NORMAL;
		pstVarScope->min.dbValue = 0;
		pstVarScope->max.bFloating = FALSE;
		pstVarScope->max.ucValueFlag = TRVALUE_NORMAL;
		pstVarScope->max.dbValue = value - 1;
	}
}
/* return a value-scope of astLinkType TYPE
 *   basic type
 *   pointer
 *   function
 *   bit-field
 *   enumeration
 *  */
/*debug,12/10/19,S*/
VOID DLL_EXPORT Tr_ScpGetScpByType(AST astLinkType,TRVALUESCP * pstVarScope) {
/*debug,12/10/19,E*/
	U4 size = LinkTypeInfo.getTypeSize(astLinkType);
	if (LinkTypeInfo.isBasicType(astLinkType)) {
		if (LinkTypeInfo.isFloating(astLinkType)) {
			Tr_ScpGetMinMaxByBytes(pstVarScope, size, TRUE, TRUE);
		} else if (LinkTypeInfo.isInteger(astLinkType)) {
			/* integer */
			Tr_ScpGetMinMaxByBytes(pstVarScope, size,
					LinkTypeInfo.isSigned(astLinkType), FALSE);
		} else {
			/* void */
			pstVarScope->usScopeKind = SCOPEKIND_NAN;
		}
	} else if (LinkTypeInfo.isEnum(astLinkType)) {
		Tr_ScpGetMinMaxByBytes(pstVarScope, size,
				LinkTypeInfo.isSigned(astLinkType), FALSE);
	} else if (LinkTypeInfo.isPointer(astLinkType)) {
		Tr_ScpGetMinMaxByBytes(pstVarScope, size, FALSE, FALSE);
		pstVarScope->bAddress = TRUE;
	} else if (LinkTypeInfo.isFunction(astLinkType)) {
		pstVarScope->bSigned = FALSE;
		if (stCoreEnvInfo.ucNearFar) {
			size = FARPOINTERSIZE;
		} else {
			size = POINTERSIZE;
		}
		Tr_ScpGetMinMaxByBytes(pstVarScope, size, FALSE, FALSE);
		pstVarScope->bAddress = TRUE;
	} else if (LinkTypeInfo.isBitfield(astLinkType)) {
		Tr_ScpGetMinMaxByBits(pstVarScope, size,
				LinkTypeInfo.isSigned(astLinkType));
	} else {
		Tr_ScpGetDefaultNan(pstVarScope);
	}
}
/* get value scope from a variable */
static VOID tr_ScpOperandVari(AST astVari, TRVALUESCP *pstVarScope) {
	AST astLinkType;
	AST astTrVari;

	assert( astVari != 0);
	assert( pstVarScope != NULL);
	/* If the value scope of this variable is recorded,
	 *  return the recorded scope.
	 * Otherwise, return the scope of its type.
	 */
	astTrVari = Tr_VarBlkGetVari(astVari, Tr_PathParamGetCurrVariBlock());
	if (astTrVari) {
		if (Tr_VariNeedCalcuteScp(astTrVari)) {
			Tr_VariGetScope(astTrVari, pstVarScope);
			return;
		}
	}
	astLinkType = LinkVariable.getType(astVari);
	Tr_ScpGetScpByType(astLinkType, pstVarScope);
}
/* get value scope from a constant */
static VOID tr_ScpOperandConstant(AST astConst, TRVALUESCP *pstVarScope) {

	assert( astConst != 0);
	assert( pstVarScope != NULL);
	pstVarScope->size = LinkConstant.getSize(astConst);
	pstVarScope->bBit = FALSE;
	pstVarScope->bSigned = LinkConstant.isSigned(astConst);
	pstVarScope->calError = 0;
	pstVarScope->bAddress = FALSE;
	pstVarScope->bFloat = LinkConstant.isFloating(astConst);

	/* get value from the constant, and set to min and max */
	if (LinkConstant.isFloating(astConst)) {
		Tr_ValueNewFloating(LinkConstant.getFloating(astConst),
				&pstVarScope->min);
	} else {
		Tr_ValueNewInteger(LinkConstant.getInteger(astConst),
				&pstVarScope->min);
	}
	pstVarScope->max = pstVarScope->min;
	pstVarScope->usScopeKind = SCOPEKIND_IN;
}
/* get scope of -A from scope of A */
static VOID tr_ScpSingleMinus(TRVALUESCP *pstVarScope1, TRVALUESCP *pstVarScope) {
	TRVALUESCP typeScope;
	TRVALUE one;

	*pstVarScope = *pstVarScope1;
	if (pstVarScope1->usScopeKind == SCOPEKIND_VOID) {
		return;
	}
	if (pstVarScope1->usScopeKind == SCOPEKIND_NAN) {
		return;
	}
	if (pstVarScope->bFloat) {
		Tr_ValueMinus(&pstVarScope1->min, &pstVarScope->max);
		Tr_ValueMinus(&pstVarScope1->max, &pstVarScope->min);
		return;
	}
	Tr_ValueNewOne(&one, FALSE);
	Tr_ScpGetMinMaxByBytes(&typeScope, pstVarScope->size, pstVarScope->bSigned,
			pstVarScope->bFloat);
	pstVarScope->calError = 0;
	if (pstVarScope->usScopeKind == SCOPEKIND_IN) {
		if (Tr_ValueEqual(&pstVarScope->min, &typeScope.min)) {
			Tr_ValueMinus(&pstVarScope1->max, &pstVarScope->max);
			if (pstVarScope->bSigned == FALSE) {
				Tr_ValueAdd(&typeScope.max, &pstVarScope->max,
						&pstVarScope->max);
				Tr_ValueAdd(&one, &pstVarScope->max, &pstVarScope->max);
			}
			pstVarScope->usScopeKind = SCOPEKIND_OUT;
		} else {
			Tr_ValueMinus(&pstVarScope1->min, &pstVarScope->max);
			if (pstVarScope->bSigned == FALSE) {
				Tr_ValueAdd(&typeScope.max, &pstVarScope->max,
						&pstVarScope->max);
				Tr_ValueAdd(&one, &pstVarScope->max, &pstVarScope->max);
			}
			Tr_ValueMinus(&pstVarScope1->max, &pstVarScope->min);
			if (pstVarScope->bSigned == FALSE) {
				Tr_ValueAdd(&typeScope.max, &pstVarScope->min,
						&pstVarScope->min);
				Tr_ValueAdd(&one, &pstVarScope->min, &pstVarScope->min);
			}
			pstVarScope->usScopeKind = SCOPEKIND_IN;
		}
	} else {
		if (Tr_ValueEqual(&pstVarScope->min, &typeScope.min)) {
			Tr_ValueMinus(&pstVarScope1->max, &pstVarScope->max);
			if (pstVarScope->bSigned == FALSE) {
				Tr_ValueAdd(&typeScope.max, &pstVarScope->max,
						&pstVarScope->max);
				Tr_ValueAdd(&one, &pstVarScope->max, &pstVarScope->max);
			}
			pstVarScope->usScopeKind = SCOPEKIND_IN;
		} else {
			Tr_ValueMinus(&pstVarScope1->min, &pstVarScope->max);
			if (pstVarScope->bSigned == FALSE) {
				Tr_ValueAdd(&typeScope.max, &pstVarScope->max,
						&pstVarScope->max);
				Tr_ValueAdd(&one, &pstVarScope->max, &pstVarScope->max);
			}
			Tr_ValueMinus(&pstVarScope1->max, &pstVarScope->min);
			if (pstVarScope->bSigned == FALSE) {
				Tr_ValueAdd(&typeScope.max, &pstVarScope->min,
						&pstVarScope->min);
				Tr_ValueAdd(&one, &pstVarScope->min, &pstVarScope->min);
			}
			pstVarScope->usScopeKind = SCOPEKIND_OUT;
		}
	}
}
/* get scope of A+B from scopes of A and B */
static VOID tr_ScpBinaryAdd(TRVALUESCP *pstVarScope1, TRVALUESCP *pstVarScope2,
		TRVALUESCP *pstVarScope) {
	TRVALUESCP typeScope;

	if (pstVarScope1->usScopeKind == SCOPEKIND_VOID) {
		*pstVarScope = *pstVarScope1;
	} else if (pstVarScope2->usScopeKind == SCOPEKIND_VOID) {
		*pstVarScope = *pstVarScope2;
	} else if (pstVarScope1->usScopeKind == SCOPEKIND_NAN) {
		*pstVarScope = *pstVarScope1;
	} else if (pstVarScope2->usScopeKind == SCOPEKIND_NAN) {
		*pstVarScope = *pstVarScope2;
	} else {
		Tr_ScpArithPromotionFlags(pstVarScope1, pstVarScope2, pstVarScope);
		if (pstVarScope->bAddress == FALSE) {
			Tr_ScpGetMinMaxByBytes(&typeScope, pstVarScope->size,
					pstVarScope->bSigned, pstVarScope->bFloat);
			Tr_ScpAdjustByScp(pstVarScope1, &typeScope);
			Tr_ScpAdjustByScp(pstVarScope2, &typeScope);
		}
		if ((pstVarScope1->usScopeKind == SCOPEKIND_IN)
				&& (pstVarScope2->usScopeKind == SCOPEKIND_IN)) {
			pstVarScope->calError = 0;
			Tr_ValueAdd(&pstVarScope1->min, &pstVarScope2->min,
					&pstVarScope->min);
			Tr_ValueAdd(&pstVarScope1->max, &pstVarScope2->max,
					&pstVarScope->max);
			pstVarScope->usScopeKind = SCOPEKIND_IN;
			if (!Tr_ValueIsNormal(&pstVarScope->min)) {
				pstVarScope->calError = CALERROR_OVERFLOW;
				pstVarScope->usScopeKind = SCOPEKIND_NAN;
			}
			if (!Tr_ValueIsNormal(&pstVarScope->max)) {
				pstVarScope->calError = CALERROR_OVERFLOW;
				pstVarScope->usScopeKind = SCOPEKIND_NAN;
			}
		} else if (pstVarScope1->usScopeKind == SCOPEKIND_IN) {
			Tr_ScpGetMinMaxByBytes(&typeScope, pstVarScope2->size,
					pstVarScope2->bSigned, pstVarScope2->bFloat);
			Tr_ValueAdd(&pstVarScope1->min, &typeScope.min, &pstVarScope->min);
			Tr_ValueAdd(&pstVarScope1->max, &typeScope.max, &pstVarScope->max);
			pstVarScope->usScopeKind = SCOPEKIND_IN;
			if (!Tr_ValueIsNormal(&pstVarScope->min)) {
				pstVarScope->calError = CALERROR_OVERFLOW;
				pstVarScope->usScopeKind = SCOPEKIND_NAN;
			}
			if (!Tr_ValueIsNormal(&pstVarScope->max)) {
				pstVarScope->calError = CALERROR_OVERFLOW;
				pstVarScope->usScopeKind = SCOPEKIND_NAN;
			}
		} else if (pstVarScope2->usScopeKind == SCOPEKIND_IN) {
			Tr_ScpGetMinMaxByBytes(&typeScope, pstVarScope2->size,
					pstVarScope2->bSigned, pstVarScope2->bFloat);
			Tr_ValueAdd(&pstVarScope2->min, &typeScope.min, &pstVarScope->min);
			Tr_ValueAdd(&pstVarScope2->max, &typeScope.max, &pstVarScope->max);
			pstVarScope->usScopeKind = SCOPEKIND_IN;
			if (!Tr_ValueIsNormal(&pstVarScope->min)) {
				pstVarScope->calError = CALERROR_OVERFLOW;
				pstVarScope->usScopeKind = SCOPEKIND_NAN;
			}
			if (!Tr_ValueIsNormal(&pstVarScope->max)) {
				pstVarScope->calError = CALERROR_OVERFLOW;
				pstVarScope->usScopeKind = SCOPEKIND_NAN;
			}
		} else {
			Tr_ScpGetMinMaxByBytes(&typeScope, pstVarScope1->size,
					pstVarScope1->bSigned, pstVarScope1->bFloat);
			Tr_ValueAdd(&typeScope.min, &typeScope.min, &pstVarScope->min);
			Tr_ValueAdd(&typeScope.max, &typeScope.max, &pstVarScope->max);
			pstVarScope->usScopeKind = SCOPEKIND_IN;
			if (!Tr_ValueIsNormal(&pstVarScope->min)) {
				pstVarScope->calError = CALERROR_OVERFLOW;
				pstVarScope->usScopeKind = SCOPEKIND_NAN;
			}
			if (!Tr_ValueIsNormal(&pstVarScope->max)) {
				pstVarScope->calError = CALERROR_OVERFLOW;
				pstVarScope->usScopeKind = SCOPEKIND_NAN;
			}
		}
	}
}
/* get scope of A-B from scopes of A and B */
static VOID tr_ScpBinarySub(TRVALUESCP *pstVarScope1, TRVALUESCP *pstVarScope2,
		TRVALUESCP *pstVarScope) {
	TRVALUESCP temp;
	tr_ScpSingleMinus(pstVarScope2, &temp);
	tr_ScpBinaryAdd(pstVarScope1, &temp, pstVarScope);
}
/* get scope of A*B from scopes of A and B */
static VOID tr_ScpBinaryMul(TRVALUESCP *pstVarScope1, TRVALUESCP *pstVarScope2,
		TRVALUESCP *pstVarScope) {
	TRVALUE stTmpValue;
	TRVALUE stMin;
	TRVALUE stMax;
	TRVALUE stMin1;
	TRVALUE stMin2;
	TRVALUE stMax1;
	TRVALUE stMax2;
	TRVALUESCP typeScope;

	if (pstVarScope1->usScopeKind == SCOPEKIND_VOID) {
		*pstVarScope = *pstVarScope1;
	} else if (pstVarScope2->usScopeKind == SCOPEKIND_VOID) {
		*pstVarScope = *pstVarScope2;
	} else if (pstVarScope1->usScopeKind == SCOPEKIND_NAN) {
		*pstVarScope = *pstVarScope1;
	} else if (pstVarScope2->usScopeKind == SCOPEKIND_NAN) {
		*pstVarScope = *pstVarScope2;
	} else {
		Tr_ScpArithPromotionFlags(pstVarScope1, pstVarScope2, pstVarScope);
		Tr_ScpGetMinMaxByBytes(&typeScope, pstVarScope->size,
				pstVarScope->bSigned, pstVarScope->bFloat);
		Tr_ScpAdjustByScp(pstVarScope1, &typeScope);
		Tr_ScpAdjustByScp(pstVarScope2, &typeScope);

		*pstVarScope = *pstVarScope1;
		pstVarScope->calError = FALSE;
		if (pstVarScope1->usScopeKind == SCOPEKIND_IN) {
			stMin1 = pstVarScope1->min;
			stMax1 = pstVarScope1->max;
		} else {
			stMin1 = typeScope.min;
			stMax1 = typeScope.max;
		}
		if (pstVarScope2->usScopeKind == SCOPEKIND_IN) {
			stMin2 = pstVarScope2->min;
			stMax2 = pstVarScope2->max;
		} else {
			stMin2 = typeScope.min;
			stMax2 = typeScope.max;
		}
		/* min value */
		Tr_ValueMul(&stMin1, &stMin2, &stMin);
		Tr_ValueMul(&stMax1, &stMax2, &stTmpValue);
		if (!Tr_ValueIsNormal(&stTmpValue)) {
			stMin = stTmpValue;
		} else {
			if (Tr_ValueLessThan(&stTmpValue, &stMin)) {
				stMin = stTmpValue;
			}
			Tr_ValueMul(&stMax1, &stMin2, &stTmpValue);
			if (!Tr_ValueIsNormal(&stTmpValue)) {
				stMin = stTmpValue;
			} else {
				if (Tr_ValueLessThan(&stTmpValue, &stMin)) {
					stMin = stTmpValue;
				}
				Tr_ValueMul(&stMax1, &stMax2, &stTmpValue);
				if (!Tr_ValueIsNormal(&stTmpValue)) {
					stMin = stTmpValue;
				} else {
					if (Tr_ValueLessThan(&stTmpValue, &stMin)) {
						stMin = stTmpValue;
					}
				}
			}
		}

		/* max value */
		Tr_ValueMul(&stMax1, &stMax2, &stMax);
		Tr_ValueMul(&stMax1, &stMin2, &stTmpValue);
		if (!Tr_ValueIsNormal(&stTmpValue)) {
			stMax = stTmpValue;
		} else {
			if (Tr_ValueLessThan(&stMax, &stTmpValue)) {
				stMax = stTmpValue;
			}
			Tr_ValueMul(&stMin1, &stMax2, &stTmpValue);
			if (!Tr_ValueIsNormal(&stTmpValue)) {
				stMax = stTmpValue;
			} else {
				if (Tr_ValueLessThan(&stMax, &stTmpValue)) {
					stMax = stTmpValue;
				}
				Tr_ValueMul(&stMin1, &stMin2, &stTmpValue);
				if (!Tr_ValueIsNormal(&stTmpValue)) {
					stMax = stTmpValue;
				} else {
					if (Tr_ValueLessThan(&stMax, &stTmpValue)) {
						stMax = stTmpValue;
					}
				}
			}
		}

		pstVarScope->usScopeKind = SCOPEKIND_IN;
		if (!Tr_ValueIsNormal(&stMin)) {
			pstVarScope->calError = CALERROR_OVERFLOW;
			pstVarScope->usScopeKind = SCOPEKIND_NAN;
		} else {
			pstVarScope->min = stMin;
		}
		if (!Tr_ValueIsNormal(&stMax)) {
			pstVarScope->calError = CALERROR_OVERFLOW;
			pstVarScope->usScopeKind = SCOPEKIND_NAN;
		} else {
			pstVarScope->max = stMax;
		}
	}
}
/* get scope of A/B from scopes of A and B.
 *  */
static VOID tr_ScpBinaryDiv(TRVALUESCP *pstVarScope1, TRVALUESCP *pstVarScope2,
		TRVALUESCP *pstVarScope) {
	TRVALUESCP typeScope;
	if (pstVarScope1->usScopeKind == SCOPEKIND_VOID) {
		*pstVarScope = *pstVarScope1;
	} else if (pstVarScope2->usScopeKind == SCOPEKIND_VOID) {
		*pstVarScope = *pstVarScope2;
	} else if (pstVarScope1->usScopeKind == SCOPEKIND_NAN) {
		*pstVarScope = *pstVarScope1;
	} else if (pstVarScope2->usScopeKind == SCOPEKIND_NAN) {
		*pstVarScope = *pstVarScope2;
	} else {
		Tr_ScpArithPromotionFlags(pstVarScope1, pstVarScope2, pstVarScope);
		Tr_ScpGetMinMaxByBytes(&typeScope, pstVarScope->size,
				pstVarScope->bSigned, pstVarScope->bFloat);
		Tr_ScpAdjustByScp(pstVarScope1, &typeScope);
		Tr_ScpAdjustByScp(pstVarScope2, &typeScope);
		if (pstVarScope2->usScopeKind == SCOPEKIND_IN) {
			if (Tr_ValueEqual(&pstVarScope2->min, &pstVarScope2->max)
					&& Tr_ValueIsZero(&pstVarScope2->min)) {
				pstVarScope->calError = CALERROR_DIVIDE_ZERO;
				pstVarScope->usScopeKind = SCOPEKIND_NAN;
				return;
			}
		}
		if (pstVarScope1->min.bFloating) {
			Tr_ScpGetMinMaxByBytes(pstVarScope, pstVarScope1->size,
					pstVarScope1->bSigned, pstVarScope1->bFloat);
		} else {
			*pstVarScope = *pstVarScope1;
			if (pstVarScope1->usScopeKind == SCOPEKIND_IN) {
				pstVarScope->min = pstVarScope1->min;
				pstVarScope->max = pstVarScope1->max;
				pstVarScope->usScopeKind = SCOPEKIND_IN;
			} else {
				Tr_ScpGetMinMaxByBytes(pstVarScope, pstVarScope1->size,
						pstVarScope1->bSigned, pstVarScope1->bFloat);
			}
		}
	}
}
/* get scope of A%B from scopes of A and B.
 *  */
static VOID tr_ScpBinaryMod(TRVALUESCP *pstVarScope1, TRVALUESCP *pstVarScope2,
		TRVALUESCP *pstVarScope) {
	TRVALUESCP typeScope;
	if (pstVarScope1->usScopeKind == SCOPEKIND_VOID) {
		*pstVarScope = *pstVarScope1;
	} else if (pstVarScope2->usScopeKind == SCOPEKIND_VOID) {
		*pstVarScope = *pstVarScope2;
	} else if (pstVarScope1->usScopeKind == SCOPEKIND_NAN) {
		*pstVarScope = *pstVarScope1;
	} else if (pstVarScope2->usScopeKind == SCOPEKIND_NAN) {
		*pstVarScope = *pstVarScope2;
	} else {
		Tr_ScpArithPromotionFlags(pstVarScope1, pstVarScope2, pstVarScope);
		Tr_ScpGetMinMaxByBytes(&typeScope, pstVarScope->size,
				pstVarScope->bSigned, pstVarScope->bFloat);
		Tr_ScpAdjustByScp(pstVarScope1, &typeScope);
		Tr_ScpAdjustByScp(pstVarScope2, &typeScope);
		if (pstVarScope2->usScopeKind == SCOPEKIND_IN) {
			if (Tr_ValueEqual(&pstVarScope2->min, &pstVarScope2->max)
					&& Tr_ValueIsZero(&pstVarScope2->min)) {
				pstVarScope->calError = CALERROR_DIVIDE_ZERO;
				pstVarScope->usScopeKind = SCOPEKIND_NAN;
				return;
			}
		}
		if (pstVarScope1->min.bFloating) {
			pstVarScope->usScopeKind = SCOPEKIND_NAN;
		} else {
			if (pstVarScope2->usScopeKind == SCOPEKIND_IN) {
				*pstVarScope = *pstVarScope2;
			} else {
				Tr_ScpGetMinMaxByBytes(pstVarScope, pstVarScope2->size,
						pstVarScope2->bSigned, pstVarScope2->bFloat);
			}
		}
	}
}
/* get scope of operand
 *  */
static VOID tr_ScpOperand(AST astOperand, TRVALUESCP *pstVarScope) {
	AST astLinkType;
	AST astParameter;

	assert( astOperand != 0);
	assert( pstVarScope != NULL);
	if (LinkOperand.isVariable(astOperand)) {
		astParameter = LinkOperand.getParameter(astOperand);
		tr_ScpOperandVari(astParameter, pstVarScope);
	} else if (LinkOperand.isFunction(astOperand)) {
		astParameter = LinkOperand.getParameter(astOperand);
		astLinkType = LinkFunction.getType(astParameter);
		Tr_ScpGetScpByType(astLinkType, pstVarScope);
	} else if (LinkOperand.isCommandList(astOperand)) {
		astParameter = LinkOperand.getParameter(astOperand);
		Tr_ScpGetCmdValue(astParameter, pstVarScope);
	} else if (LinkOperand.isConstant(astOperand)) {
		astParameter = LinkOperand.getParameter(astOperand);
		tr_ScpOperandConstant(astParameter, pstVarScope);
	} else {
		pstVarScope->usScopeKind = SCOPEKIND_NAN;
	}
}
/* get scope of a ASM_CMD_MINUS
 *  */
static VOID tr_ScpCmdMinus(AST astCmdList, TRVALUESCP *pstVarScope) {
	TRVALUESCP stTmp;
	AST astLeftOperand;
	AST astLinkType;

	astLeftOperand = LinkCommandList.getLeftOperand(astCmdList);
	tr_ScpOperand(astLeftOperand, &stTmp);
	if (stTmp.usScopeKind != SCOPEKIND_NAN) {
		tr_ScpSingleMinus(&stTmp, pstVarScope);
		if (pstVarScope->usScopeKind == SCOPEKIND_NAN) {
			astLinkType = LinkCommandList.getType(astCmdList);
			Tr_ScpGetScpByType(astLinkType, pstVarScope);
		}
	} else {
		astLinkType = LinkCommandList.getType(astCmdList);
		Tr_ScpGetScpByType(astLinkType, pstVarScope);
	}
}
/*debug,12/10/22,S*/
/* get scope of a ASM_CMD_CAST*/
static VOID tr_ScpCmdCast(AST astCmdList, TRVALUESCP *pstVarScope) {
	AST castType;
	AST castedOpIdx;
	TRVALUESCP result;

	castType = LinkCommandList.getType(astCmdList);
	Tr_ScpGetScpByType(castType,pstVarScope);
	castedOpIdx = LinkCommandList.getLeftOperand(astCmdList);
	tr_ScpOperand(castedOpIdx, &result);
	Tr_ScpAdjustByScp(pstVarScope, &result);
}
/*debug,12/10/22,E*/
/* get scope of a ASM_CMD_ADD
 *  */
static VOID tr_ScpCmdAdd(AST astCmdList, TRVALUESCP *pstVarScope) {
	TRVALUESCP stTmp;
	TRVALUESCP stTmp2;
	AST astLeft;
	AST astRight;
	AST astLinkType;

	astLeft = LinkCommandList.getLeftOperand(astCmdList);
	astRight = LinkCommandList.getRightOperand(astCmdList);
	tr_ScpOperand(astLeft, &stTmp);
	tr_ScpOperand(astRight, &stTmp2);
	if (stTmp.usScopeKind != SCOPEKIND_NAN
			&& stTmp2.usScopeKind != SCOPEKIND_NAN) {
		tr_ScpBinaryAdd(&stTmp, &stTmp2, pstVarScope);
		if (pstVarScope->usScopeKind == SCOPEKIND_NAN) {
			astLinkType = LinkCommandList.getType(astCmdList);
			Tr_ScpGetScpByType(astLinkType, pstVarScope);
		}
	} else {
		astLinkType = LinkCommandList.getType(astCmdList);
		Tr_ScpGetScpByType(astLinkType, pstVarScope);
	}

}
/* get scope of a ASM_CMD_SUB
 *  */
static VOID tr_ScpCmdSub(AST astCmdList, TRVALUESCP *pstVarScope) {
	TRVALUESCP stTmp;
	TRVALUESCP stTmp2;
	AST astLeft;
	AST astRight;
	AST astLinkType;

	astLeft = LinkCommandList.getLeftOperand(astCmdList);
	astRight = LinkCommandList.getRightOperand(astCmdList);
	tr_ScpOperand(astLeft, &stTmp);
	tr_ScpOperand(astRight, &stTmp2);
	if (stTmp.usScopeKind != SCOPEKIND_NAN
			&& stTmp2.usScopeKind != SCOPEKIND_NAN) {
		tr_ScpBinarySub(&stTmp, &stTmp2, pstVarScope);
		if (pstVarScope->usScopeKind == SCOPEKIND_NAN) {
			astLinkType = LinkCommandList.getType(astCmdList);
			Tr_ScpGetScpByType(astLinkType, pstVarScope);
		}
	} else {
		astLinkType = LinkCommandList.getType(astCmdList);
		Tr_ScpGetScpByType(astLinkType, pstVarScope);
	}
}
/* get scope of a ASM_CMD_MUL
 *  */
static VOID tr_ScpCmdMul(AST astCmdList, TRVALUESCP *pstVarScope) {
	TRVALUESCP stTmp;
	TRVALUESCP stTmp2;
	AST astLeft;
	AST astRight;
	AST astLinkType;

	astLeft = LinkCommandList.getLeftOperand(astCmdList);
	astRight = LinkCommandList.getRightOperand(astCmdList);
	tr_ScpOperand(astLeft, &stTmp);
	tr_ScpOperand(astRight, &stTmp2);
	if (stTmp.usScopeKind != SCOPEKIND_NAN
			&& stTmp2.usScopeKind != SCOPEKIND_NAN) {
		tr_ScpBinaryMul(&stTmp, &stTmp2, pstVarScope);
		if (pstVarScope->usScopeKind == SCOPEKIND_NAN) {
			astLinkType = LinkCommandList.getType(astCmdList);
			Tr_ScpGetScpByType(astLinkType, pstVarScope);
		}
	} else {
		astLinkType = LinkCommandList.getType(astCmdList);
		Tr_ScpGetScpByType(astLinkType, pstVarScope);
	}

}
/* get scope of a ASM_CMD_DIV
 *  */
static VOID tr_ScpCmdDiv(AST astCmdList, TRVALUESCP *pstVarScope) {
	TRVALUESCP stTmp;
	TRVALUESCP stTmp2;
	AST astLeft;
	AST astRight;
	AST astLinkType;

	astLeft = LinkCommandList.getLeftOperand(astCmdList);
	astRight = LinkCommandList.getRightOperand(astCmdList);
	tr_ScpOperand(astLeft, &stTmp);
	tr_ScpOperand(astRight, &stTmp2);
	if (stTmp.usScopeKind != SCOPEKIND_NAN
			&& stTmp2.usScopeKind != SCOPEKIND_NAN) {
		tr_ScpBinaryDiv(&stTmp, &stTmp2, pstVarScope);
		if (pstVarScope->usScopeKind == SCOPEKIND_NAN) {
			astLinkType = LinkCommandList.getType(astCmdList);
			Tr_ScpGetScpByType(astLinkType, pstVarScope);
		}
	} else {
		astLinkType = LinkCommandList.getType(astCmdList);
		Tr_ScpGetScpByType(astLinkType, pstVarScope);
	}

}
/* get scope of a ASM_CMD_MOD
 *  */
static VOID tr_ScpCmdMod(AST astCmdList, TRVALUESCP *pstVarScope) {
	TRVALUESCP stTmp;
	TRVALUESCP stTmp2;
	AST astLeft;
	AST astRight;
	AST astLinkType;

	astLeft = LinkCommandList.getLeftOperand(astCmdList);
	astRight = LinkCommandList.getRightOperand(astCmdList);
	tr_ScpOperand(astLeft, &stTmp);
	tr_ScpOperand(astRight, &stTmp2);
	if (stTmp.usScopeKind != SCOPEKIND_NAN
			&& stTmp2.usScopeKind != SCOPEKIND_NAN) {
		tr_ScpBinaryMod(&stTmp, &stTmp2, pstVarScope);
		if (pstVarScope->usScopeKind == SCOPEKIND_NAN) {
			astLinkType = LinkCommandList.getType(astCmdList);
			Tr_ScpGetScpByType(astLinkType, pstVarScope);
		}
	} else {
		astLinkType = LinkCommandList.getType(astCmdList);
		Tr_ScpGetScpByType(astLinkType, pstVarScope);
	}
}
/* get scope by the callee
 *  */
static VOID tr_ScpCmdByCall(AST astCmdList, TRVALUESCP *pstVarScope) {
	AST astLinkType;
	AST astFunction;
	AST astOpe;

	astOpe = LinkCommandList.getLeftOperand(astCmdList);
	astFunction = Tr_OpeGetFunction(astOpe);
	if (Tr_FuncIsTraced(astFunction)) {
		stTrFunctionAccess.getValueScope(astFunction, pstVarScope);
	} else {
		astLinkType = LinkCommandList.getType(astCmdList);
		Tr_ScpGetScpByType(astLinkType, pstVarScope);
	}
}
/* get scope by the type of command list
 *  */
static VOID tr_ScpCmdByType(AST astCmdList, TRVALUESCP *pstVarScope) {
	AST astLinkType;
	astLinkType = LinkCommandList.getType(astCmdList);
	Tr_ScpGetScpByType(astLinkType, pstVarScope);
}
/* get scope of BOOL command
 *  */
static VOID tr_ScpCmdJudge(AST astCmdList, TRVALUESCP *pstVarScope) {
	Tr_ScpGetMinMaxByBytes(pstVarScope, INTSIZE, TRUE, FALSE );
	Tr_ValueNewZero( &pstVarScope->min, FALSE );
	Tr_ValueNewOne( &pstVarScope->max, FALSE );
}
/* get scope of command*/
/*debug,12/10/22,S*/
VOID DLL_EXPORT Tr_ScpGetCmdValue(AST astCmdList, TRVALUESCP *pstVarScope) {
/*debug,12/10/22,E*/
	U4 kind = stCmdListAccess.opKind.get(astCmdList);
	AST astLeft;

	assert( pstVarScope != NULL);
	switch (kind) {
	case ASM_CMD_NOP:
	case ASM_CMD_RETURN:
	case ASM_CMD_CHOOSE:
	case ASM_CMD_CHOOSEEND:
	case ASM_CMD_CONFLUX:
	case ASM_CMD_JUMP:
	case ASM_CMD_JUDGE:
	case ASM_CMD_BRANCH:
	case ASM_CMD_FUNCENTRY:
	case ASM_CMD_FUNCEXIT:
		Tr_ScpGetDefaultNan(pstVarScope);
		break;
	case ASM_CMD_GETOPERAND:
		tr_ScpOperand(LinkCommandList.getLeftOperand(astCmdList), pstVarScope);
		break;
	case ASM_CMD_GETOFFSET_UNIT:
	case ASM_CMD_GETOFFSET:
	case ASM_CMD_GETMEMDATA:
	case ASM_CMD_GETADDR:
		tr_ScpCmdByType(astCmdList, pstVarScope);
		break;
	case ASM_CMD_CALL:
		tr_ScpCmdByCall(astCmdList, pstVarScope);
		break;
	case ASM_CMD_INC:
	case ASM_CMD_DEC:
		astLeft = LinkCommandList.getLeftOperand(astCmdList);
		Tr_ScpGetCmdValue(astLeft, pstVarScope);
		break;
	case ASM_CMD_MINUS:
		tr_ScpCmdMinus(astCmdList, pstVarScope);
		break;
	case ASM_CMD_NEGATION:
		//TODO
//		tr_ScpCmdNeg(astCmdList, pstVarScope);
		break;
	case ASM_CMD_BITNEGATION:
		//TODO
//		tr_ScpCmdBitNeg(astCmdList, pstVarScope);
		break;
	case ASM_CMD_CAST:
		/*debug,12/10/22,S*/
		tr_ScpCmdCast(astCmdList, pstVarScope);
		/*debug,12/10/22,E*/
		break;
	case ASM_CMD_MUL:
		tr_ScpCmdMul(astCmdList, pstVarScope);
		break;
	case ASM_CMD_DIV:
		tr_ScpCmdDiv(astCmdList, pstVarScope);
		break;
	case ASM_CMD_MOD:
		tr_ScpCmdMod(astCmdList, pstVarScope);
		break;
	case ASM_CMD_ADD:
		tr_ScpCmdAdd(astCmdList, pstVarScope);
		break;
	case ASM_CMD_SUB:
		tr_ScpCmdSub(astCmdList, pstVarScope);
		break;
	case ASM_CMD_LSFT:
	case ASM_CMD_RSFT:
		tr_ScpCmdByType(astCmdList, pstVarScope);
		break;
	case ASM_CMD_GREATER:
	case ASM_CMD_GREATEREQUAL:
	case ASM_CMD_LESS:
	case ASM_CMD_LESSEQUAL:
	case ASM_CMD_EQUAL:
	case ASM_CMD_UNEQUAL:
		tr_ScpCmdJudge(astCmdList, pstVarScope);
		break;
	case ASM_CMD_BITAND:
	case ASM_CMD_BITEXOR:
	case ASM_CMD_BITINOR:
		tr_ScpCmdByType(astCmdList, pstVarScope);
		break;
	case ASM_CMD_LGAND:
	case ASM_CMD_LGOR:
		tr_ScpCmdJudge(astCmdList, pstVarScope);
		break;
	case ASM_CMD_ASSIGN:
	case ASM_CMD_ASSIGNARG:
		astLeft = LinkCommandList.getLeftOperand(astCmdList);
		Tr_ScpGetCmdValue(astLeft, pstVarScope);
		break;
	}
}
VOID Tr_ScpArithPromotionFlags(TRVALUESCP *stLeft, TRVALUESCP *stRight,
		TRVALUESCP *stResult) {
	if (stLeft->bAddress && stRight->bAddress) {
		stResult->bAddress = FALSE;
	} else if (stLeft->bAddress || stRight->bAddress) {
		stResult->bAddress = TRUE;
	} else {
		stResult->bAddress = FALSE;
	}
	stResult->bBit = FALSE;
	if (stLeft->bFloat && stRight->bFloat) {
		stResult->size =
				stLeft->size > stRight->size ? stLeft->size : stRight->size;
		stResult->bFloat = TRUE;
	} else if (stLeft->bFloat) {
		stResult->bFloat = TRUE;
		stResult->size = stLeft->size;
	} else if (stRight->bFloat) {
		stResult->bFloat = TRUE;
		stResult->size = stRight->size;
	} else {
		if (stLeft->size > stRight->size) {
			stResult->size = stLeft->size;
			stResult->bSigned = stLeft->bSigned;
		} else if (stLeft->size < stRight->size) {
			stResult->size = stRight->size;
			stResult->bSigned = stRight->bSigned;
		} else {
			if (!stLeft->bSigned || !stRight->bSigned) {
				stResult->size = stRight->size;
				stResult->bSigned = FALSE;
			} else {
				stResult->size = stRight->size;
				stResult->bSigned = TRUE;
			}
		}
		stResult->bFloat = FALSE;
	}
}
/* get the intersection of stLeft and stRight, and save to stResult */
VOID Tr_ScpMergeAndAnd(
		TRVALUESCP *stLeft, TRVALUESCP *stRight, TRVALUESCP *stResult) {
	TRVALUESCP *pstMin;
	TRVALUESCP *pstMax;
	TRVALUESCP typeScp;
	if (stLeft->usScopeKind == SCOPEKIND_VOID) {
		*stResult = *stLeft;
	} else if (stRight->usScopeKind == SCOPEKIND_VOID) {
		*stResult = *stRight;
	} else if (stLeft->usScopeKind == SCOPEKIND_NAN) {
		*stResult = *stLeft;
	} else if (stRight->usScopeKind == SCOPEKIND_NAN) {
		*stResult = *stRight;
	} else if (stLeft->usScopeKind == SCOPEKIND_IN
			&& stRight->usScopeKind == SCOPEKIND_IN) {
		Tr_ScpArithPromotionFlags(stLeft, stRight, stResult);
		Tr_ScpGetMinMaxByBytes(&typeScp, stResult->size, stResult->bSigned,
				stResult->bFloat);
		Tr_ScpAdjustByScp(stLeft, &typeScp);
		Tr_ScpAdjustByScp(stRight, &typeScp);
		if (Tr_ValueLessThan(&stLeft->min, &stRight->min)) {
			pstMin = stRight;
		} else {
			pstMin = stLeft;
		}
		if (Tr_ValueLessThan(&stLeft->max, &stRight->max)) {
			pstMax = stLeft;
		} else {
			pstMax = stRight;
		}

		if (Tr_ValueLessThan(&pstMax->max, &pstMin->min)) {
			stResult->usScopeKind = SCOPEKIND_VOID;
		} else {
			stResult->usScopeKind = SCOPEKIND_IN;
			stResult->min = pstMin->min;
			stResult->max = pstMax->max;
		}
	} else if (stLeft->usScopeKind == SCOPEKIND_IN
			&& stRight->usScopeKind == SCOPEKIND_OUT) {
		Tr_ScpArithPromotionFlags(stLeft, stRight, stResult);
		Tr_ScpGetMinMaxByBytes(&typeScp, stResult->size, stResult->bSigned,
				stResult->bFloat);
		Tr_ScpAdjustByScp(stLeft, &typeScp);
		Tr_ScpAdjustByScp(stRight, &typeScp);
		if (Tr_ValueLessOrEqual(&stLeft->min, &stRight->min)
				&& Tr_ValueLessOrEqual(&stRight->max, &stLeft->max)) {
			stResult->usScopeKind = SCOPEKIND_IN;
			stResult->min = stLeft->min;
			stResult->max = stLeft->max;
		} else if (Tr_ValueLessOrEqual(&stLeft->min, &stRight->min)) {
			if (Tr_ValueLessOrEqual(&stLeft->max, &stRight->min)) {
				stResult->usScopeKind = SCOPEKIND_IN;
				stResult->min = stLeft->min;
				stResult->max = stLeft->max;
			} else {
				stResult->usScopeKind = SCOPEKIND_IN;
				stResult->min = stLeft->min;
				stResult->max = stRight->max;
			}
		} else if (Tr_ValueLessOrEqual(&stRight->max, &stLeft->max)) {
			if (Tr_ValueLessOrEqual(&stRight->min, &stLeft->min)) {
				stResult->usScopeKind = SCOPEKIND_IN;
				stResult->min = stLeft->min;
				stResult->max = stLeft->max;
			} else {
				stResult->usScopeKind = SCOPEKIND_IN;
				stResult->min = stRight->max;
				stResult->max = stLeft->max;
			}
		} else {
			stResult->usScopeKind = SCOPEKIND_VOID;
		}
	} else if (stLeft->usScopeKind == SCOPEKIND_OUT
			&& stRight->usScopeKind == SCOPEKIND_IN) {
		Tr_ScpArithPromotionFlags(stLeft, stRight, stResult);
		Tr_ScpGetMinMaxByBytes(&typeScp, stResult->size, stResult->bSigned,
				stResult->bFloat);
		Tr_ScpAdjustByScp(stLeft, &typeScp);
		Tr_ScpAdjustByScp(stRight, &typeScp);
		if (Tr_ValueLessOrEqual(&stRight->min, &stLeft->min)
				&& Tr_ValueLessOrEqual(&stLeft->max, &stRight->max)) {
			stResult->usScopeKind = SCOPEKIND_IN;
			stResult->min = stRight->min;
			stResult->max = stRight->max;
		} else if (Tr_ValueLessOrEqual(&stRight->min, &stLeft->min)) {
			if (Tr_ValueLessOrEqual(&stRight->max, &stLeft->min)) {
				stResult->usScopeKind = SCOPEKIND_IN;
				stResult->min = stRight->min;
				stResult->max = stRight->max;
			} else {
				stResult->usScopeKind = SCOPEKIND_IN;
				stResult->min = stRight->min;
				stResult->max = stLeft->max;
			}
		} else if (Tr_ValueLessOrEqual(&stLeft->max, &stRight->max)) {
			if (Tr_ValueLessOrEqual(&stLeft->min, &stRight->min)) {
				stResult->usScopeKind = SCOPEKIND_IN;
				stResult->min = stRight->min;
				stResult->max = stRight->max;
			} else {
				stResult->usScopeKind = SCOPEKIND_IN;
				stResult->min = stLeft->max;
				stResult->max = stRight->max;
			}
		} else {
			stResult->usScopeKind = SCOPEKIND_VOID;
		}
	} else {
		Tr_ScpArithPromotionFlags(stLeft, stRight, stResult);
		Tr_ScpGetMinMaxByBytes(&typeScp, stResult->size, stResult->bSigned,
				stResult->bFloat);
		Tr_ScpAdjustByScp(stLeft, &typeScp);
		Tr_ScpAdjustByScp(stRight, &typeScp);
		if (Tr_ValueLessThan(&stRight->min, &stLeft->min)) {
			pstMin = stRight;
		} else {
			pstMin = stLeft;
		}
		if (Tr_ValueLessThan(&stLeft->max, &stRight->max)) {
			pstMax = stRight;
		} else {
			pstMax = stLeft;
		}

		if (Tr_ValueLessOrEqual(&pstMin->max, &pstMax->min)) {
			if (!Tr_ValueIsNegative(&pstMax->min)) {
				if (!Tr_ValueIsNegative(&pstMin->min)) {
					stResult->usScopeKind = SCOPEKIND_OUT;
					stResult->min = pstMax->min;
					stResult->max = pstMax->max;
				} else {
					stResult->usScopeKind = SCOPEKIND_OUT;
					stResult->min = pstMin->min;
					stResult->max = pstMin->max;
				}
			} else if (Tr_ValueIsPositive(&pstMax->max)) {
				stResult->usScopeKind = SCOPEKIND_OUT;
				stResult->min = pstMax->min;
				stResult->max = pstMax->max;
			} else {
				stResult->usScopeKind = SCOPEKIND_OUT;
				stResult->min = pstMin->min;
				stResult->max = pstMin->max;
			}
		} else {
			stResult->usScopeKind = SCOPEKIND_OUT;
			stResult->min = pstMin->min;
			stResult->max = pstMax->max;
		}
	}
}
/* get the union  of stLeft and stRight, and save to stResult */
VOID Tr_ScpMergeOrOr(
		TRVALUESCP *stLeft, TRVALUESCP *stRight, TRVALUESCP *stResult) {
	TRVALUESCP *pstMin;
	TRVALUESCP *pstMax;
	TRVALUESCP typeScp;

	if (stLeft->usScopeKind == SCOPEKIND_NAN) {
		*stResult = *stLeft;
	} else if (stRight->usScopeKind == SCOPEKIND_NAN) {
		*stResult = *stRight;
	} else if (stLeft->usScopeKind == SCOPEKIND_VOID) {
		*stResult = *stRight;
	} else if (stRight->usScopeKind == SCOPEKIND_VOID) {
		*stResult = *stLeft;
	} else if (stLeft->usScopeKind == SCOPEKIND_IN
			&& stRight->usScopeKind == SCOPEKIND_IN) {
		Tr_ScpArithPromotionFlags(stLeft, stRight, stResult);
		Tr_ScpGetMinMaxByBytes(&typeScp, stResult->size, stResult->bSigned,
				stResult->bFloat);
		Tr_ScpAdjustByScp(stLeft, &typeScp);
		Tr_ScpAdjustByScp(stRight, &typeScp);
		if (Tr_ValueLessThan(&stLeft->min, &stRight->min)) {
			pstMin = stLeft;
		} else {
			pstMin = stRight;
		}
		if (Tr_ValueLessThan(&stRight->max, &stLeft->max)) {
			pstMax = stLeft;
		} else {
			pstMax = stRight;
		}
		stResult->usScopeKind = SCOPEKIND_IN;
		stResult->min = pstMin->min;
		stResult->max = pstMax->max;
	} else if (stLeft->usScopeKind == SCOPEKIND_IN
			&& stRight->usScopeKind == SCOPEKIND_OUT) {
		Tr_ScpArithPromotionFlags(stLeft, stRight, stResult);
		Tr_ScpGetMinMaxByBytes(&typeScp, stResult->size, stResult->bSigned,
				stResult->bFloat);
		Tr_ScpAdjustByScp(stLeft, &typeScp);
		Tr_ScpAdjustByScp(stRight, &typeScp);
		if ((Tr_ValueLessThan(&stLeft->min, &typeScp.min))
				|| (Tr_ValueLessThan(&typeScp.max, &stLeft->max))) {
			stResult->usScopeKind = SCOPEKIND_IN;
			if (Tr_ValueLessThan(&stLeft->min, &typeScp.min)) {
				stResult->min = stLeft->min;
			} else {
				stResult->min = typeScp.min;
			}
			if (Tr_ValueLessThan(&typeScp.max, &stLeft->max)) {
				stResult->max = stLeft->max;
			} else {
				stResult->max = typeScp.max;
			}
		} else if ((Tr_ValueLessOrEqual(&stLeft->min, &stRight->min))
				&& (Tr_ValueLessOrEqual(&stLeft->max, &stRight->max))) {
			stResult->min = typeScp.min;
			stResult->max = typeScp.max;
			stResult->usScopeKind = SCOPEKIND_IN;
		} else if ((Tr_ValueLessOrEqual(&stLeft->min, &stRight->min))
				&& (Tr_ValueLessOrEqual(&stLeft->max, &stRight->min))) {
			/*    |---|            */
			/* |------|  |------|  */
			*stResult = *stRight;
		} else if (Tr_ValueLessOrEqual(&stLeft->min, &stRight->min)) {
			/*    |-----|            */
			/* |------|    |------|  */
			stResult->usScopeKind = SCOPEKIND_OUT;
			stResult->min = stLeft->max;
			stResult->max = stRight->max;
		} else if (Tr_ValueLessOrEqual(&stRight->max, &stLeft->min)) {
			/*             |-----|   */
			/* |------|    |------|  */
			stResult->usScopeKind = SCOPEKIND_OUT;
			stResult->min = stRight->min;
			stResult->max = stRight->max;
		} else if (Tr_ValueLessOrEqual(&stRight->max, &stLeft->max)) {
			/*          |-----|      */
			/* |------|    |------|  */
			stResult->usScopeKind = SCOPEKIND_OUT;
			stResult->min = stRight->min;
			stResult->max = stLeft->min;
		} else {
			/*          |-|           */
			/* |------|     |------|  */
			if (!Tr_ValueIsNegative(&stRight->min)) {
				stResult->usScopeKind = SCOPEKIND_OUT;
				stResult->min = stLeft->max;
				stResult->max = stRight->max;
			} else if (!Tr_ValueIsPositive(&stRight->max)) { /*  両方負数、絶対値ルール　*/
				stResult->usScopeKind = SCOPEKIND_OUT;
				stResult->min = stRight->min;
				stResult->max = stLeft->min;
			} else if (Tr_ValueIsNegative(&stLeft->max)) { /* 右範囲 0値ルール　*/
				stResult->usScopeKind = SCOPEKIND_OUT;
				stResult->min = stLeft->max;
				stResult->max = stRight->max;
			} else { /*  左範囲、0値又は負数値ルール　*/
				stResult->usScopeKind = SCOPEKIND_OUT;
				stResult->min = stRight->min;
				stResult->max = stLeft->min;
			}
		}
	} else if (stLeft->usScopeKind == SCOPEKIND_OUT
			&& stRight->usScopeKind == SCOPEKIND_IN) {
		if ((Tr_ValueLessThan(&stRight->min, &typeScp.min))
				|| (Tr_ValueLessThan(&typeScp.max, &stRight->max))) {
			stResult->usScopeKind = SCOPEKIND_IN;
			if (Tr_ValueLessThan(&stRight->min, &typeScp.min)) {
				stResult->min = stRight->min;
			} else {
				stResult->min = typeScp.min;
			}
			if (Tr_ValueLessThan(&typeScp.max, &stRight->max)) {
				stResult->max = stRight->max;
			} else {
				stResult->max = typeScp.max;
			}
		} else if ((Tr_ValueLessOrEqual(&stRight->min, &stLeft->min))
				&& (Tr_ValueLessOrEqual(&stRight->max, &stLeft->max))) {
			stResult->min = typeScp.min;
			stResult->max = typeScp.max;
			stResult->usScopeKind = SCOPEKIND_IN;
		} else if ((Tr_ValueLessOrEqual(&stRight->min, &stLeft->min))
				&& (Tr_ValueLessOrEqual(&stRight->max, &stLeft->min))) {
			/*    |---|            */
			/* |------|  |------|  */
			*stResult = *stLeft;
		} else if (Tr_ValueLessOrEqual(&stRight->min, &stLeft->min)) {
			/*    |-----|            */
			/* |------|    |------|  */
			stResult->usScopeKind = SCOPEKIND_OUT;
			stResult->min = stRight->max;
			stResult->max = stLeft->max;
		} else if (Tr_ValueLessOrEqual(&stLeft->max, &stRight->min)) {
			/*             |-----|   */
			/* |------|    |------|  */
			stResult->usScopeKind = SCOPEKIND_OUT;
			stResult->min = stLeft->min;
			stResult->max = stLeft->max;
		} else if (Tr_ValueLessOrEqual(&stLeft->max, &stRight->max)) {
			/*          |-----|      */
			/* |------|    |------|  */
			stResult->usScopeKind = SCOPEKIND_OUT;
			stResult->min = stLeft->min;
			stResult->max = stRight->min;
		} else {
			/*          |-|           */
			/* |------|     |------|  */
			if (!Tr_ValueIsNegative(&stLeft->min)) {
				stResult->usScopeKind = SCOPEKIND_OUT;
				stResult->min = stRight->max;
				stResult->max = stLeft->max;
			} else if (!Tr_ValueIsPositive(&stLeft->max)) {
				stResult->usScopeKind = SCOPEKIND_OUT;
				stResult->min = stLeft->min;
				stResult->max = stRight->min;
			} else if (Tr_ValueIsNegative(&stRight->max)) { /* 右範囲 0値ルール　*/
				stResult->usScopeKind = SCOPEKIND_OUT;
				stResult->min = stRight->max;
				stResult->max = stLeft->max;
			} else {
				stResult->usScopeKind = SCOPEKIND_OUT;
				stResult->min = stLeft->min;
				stResult->max = stRight->min;
			}
		}
	} else {
		if (Tr_ValueLessThan(&stRight->min, &stLeft->min)) {
			pstMin = stLeft;
		} else {
			pstMin = stRight;
		}
		if (Tr_ValueLessThan(&stLeft->max, &stRight->max)) {
			pstMax = stLeft;
		} else {
			pstMax = stRight;
		}
		if (Tr_ValueLessThan(&pstMin->min, &pstMax->max)) {
			stResult->usScopeKind = SCOPEKIND_OUT;
			stResult->min = pstMin->min;
			stResult->max = pstMax->max;
		} else {
			stResult->usScopeKind = SCOPEKIND_IN;
			stResult->min = typeScp.min;
			stResult->max = typeScp.max;
		}
	}
}
BOOL Tr_ScpHasValue(TRVALUESCP * pstVarScope) {
	if (pstVarScope == NULL ) {
		return FALSE;
	}
	return pstVarScope->usScopeKind != SCOPEKIND_VOID;
}
VOID Tr_ScpIncrement(TRVALUESCP *stLeft, TRVALUESCP *stResult) {
	TRVALUESCP stOne;
	if (stLeft->bAddress) {
		*stResult = *stLeft;
	} else {
		Tr_ScpGetMinMaxByBytes(&stOne, stLeft->size, stLeft->bSigned,
				stLeft->bFloat);
		Tr_ValueNewOne(&stOne.max, stLeft->bFloat);
		Tr_ValueNewOne(&stOne.min, stLeft->bFloat);
		stOne.usScopeKind = SCOPEKIND_IN;
		tr_ScpBinaryAdd(stLeft, &stOne, stResult);
	}
}
VOID Tr_ScpDecrement(TRVALUESCP *stLeft, TRVALUESCP *stResult) {
	TRVALUESCP stOne;
	if (stLeft->bAddress) {
		*stResult = *stLeft;
	} else {
		Tr_ScpGetMinMaxByBytes(&stOne, stLeft->size, stLeft->bSigned,
				stLeft->bFloat);
		Tr_ValueNewOne(&stOne.max, stLeft->bFloat);
		Tr_ValueNewOne(&stOne.min, stLeft->bFloat);
		stOne.usScopeKind = SCOPEKIND_IN;
		tr_ScpBinarySub(stLeft, &stOne, stResult);
	}
}
VOID Tr_ScpGetConstValue(AST astConst, TRVALUESCP *stResult) {
	tr_ScpOperandConstant(astConst, stResult);

}
VOID Tr_ScpGetVariValue(AST astVari, TRVALUESCP *stResult) {
	tr_ScpOperandVari(astVari, stResult);
}
VOID Tr_ScpGetOperandValue(AST astOperand, TRVALUESCP *pstVarScope) {
	tr_ScpOperand(astOperand, pstVarScope);
}
VOID Tr_ScpLimitScopeByGreater(TRVALUESCP *variScope, TRVALUESCP *pVarScope,
		TRVALUESCP *pstVarScope, BOOL bEqual) {
	TRVALUESCP typeScope;
	TRVALUESCP storageScp;
	if (variScope->usScopeKind == SCOPEKIND_VOID
			|| variScope->usScopeKind == SCOPEKIND_NAN) {
		return;
	}
	if (pVarScope->usScopeKind == SCOPEKIND_VOID
			|| pVarScope->usScopeKind == SCOPEKIND_NAN) {
		return;
	}
	Tr_ScpArithPromotionFlags(variScope, pVarScope, pstVarScope);
	Tr_ScpGetMinMaxByBytes(&typeScope, pstVarScope->size, pstVarScope->bSigned,
			pstVarScope->bFloat);
	Tr_ScpGetMinMaxByBytes(&storageScp, variScope->size, variScope->bSigned,
			variScope->bFloat);
	Tr_ScpAdjustByScp(variScope, &typeScope);
	Tr_ScpAdjustByScp(pVarScope, &typeScope);
	if (variScope->usScopeKind == SCOPEKIND_IN
			&& pVarScope->usScopeKind == SCOPEKIND_IN) {
		if (bEqual) {
			if (Tr_ValueLessThan(&variScope->max, &pVarScope->min)) {
				pstVarScope->usScopeKind = SCOPEKIND_VOID;
				Tr_ValueNewZero(&pstVarScope->min, pstVarScope->bFloat);
				Tr_ValueNewZero(&pstVarScope->max, pstVarScope->bFloat);
			} else if (Tr_ValueLessThan(&variScope->min, &pVarScope->min)) {
				pstVarScope->usScopeKind = SCOPEKIND_IN;
				pstVarScope->min = pVarScope->min;
				pstVarScope->max = variScope->max;
			} else {
				pstVarScope->usScopeKind = SCOPEKIND_IN;
				pstVarScope->min = variScope->min;
				pstVarScope->max = variScope->max;
			}
		} else {
			if (Tr_ValueLessOrEqual(&variScope->min, &pVarScope->min)
					&& Tr_ValueLessOrEqual(&variScope->max, &pVarScope->min)) {
				pstVarScope->usScopeKind = SCOPEKIND_VOID;
				Tr_ValueNewZero(&pstVarScope->min, pstVarScope->bFloat);
				Tr_ValueNewZero(&pstVarScope->max, pstVarScope->bFloat);
			} else if (Tr_ValueLessOrEqual(&variScope->min, &pVarScope->min)) {
				pstVarScope->usScopeKind = SCOPEKIND_IN;
				if (pstVarScope->bFloat) {
					pstVarScope->min = pVarScope->min;
				} else {
					Tr_ValueInc(&pVarScope->min, &pstVarScope->min);
				}
				pstVarScope->max = variScope->max;
			} else {
				pstVarScope->usScopeKind = SCOPEKIND_IN;
				pstVarScope->min = variScope->min;
				pstVarScope->max = variScope->max;
			}
		}
	} else if (variScope->usScopeKind == SCOPEKIND_IN
			&& pVarScope->usScopeKind == SCOPEKIND_OUT) {
		if (bEqual) {
			pstVarScope->usScopeKind = SCOPEKIND_IN;
			pstVarScope->min = variScope->min;
			pstVarScope->max = variScope->max;
		} else {
			if (Tr_ValueEqual(&variScope->min, &typeScope.min)) {
				pstVarScope->usScopeKind = SCOPEKIND_IN;

				if (pstVarScope->bFloat) {
					pstVarScope->min = typeScope.min;
				} else {
					Tr_ValueInc(&typeScope.min, &pstVarScope->min);
				}
				pstVarScope->max = variScope->max;
			} else {
				pstVarScope->usScopeKind = SCOPEKIND_IN;
				pstVarScope->min = variScope->min;
				pstVarScope->max = variScope->max;
			}
		}
	} else if (variScope->usScopeKind == SCOPEKIND_OUT
			&& pVarScope->usScopeKind == SCOPEKIND_IN) {
		if (bEqual) {
			if (Tr_ValueEqual(&pVarScope->min, &typeScope.min)) {
				pstVarScope->usScopeKind = SCOPEKIND_OUT;
				pstVarScope->min = variScope->min;
				pstVarScope->max = variScope->max;
			} else if (Tr_ValueLessThan(&variScope->max, &pVarScope->min)) {
				pstVarScope->usScopeKind = SCOPEKIND_IN;
				pstVarScope->min = pVarScope->min;
				pstVarScope->max = typeScope.max;
			} else if (Tr_ValueLessThan(&variScope->min, &pVarScope->min)) {
				pstVarScope->usScopeKind = SCOPEKIND_IN;
				pstVarScope->min = variScope->max;
				pstVarScope->max = typeScope.max;
			} else {
				pstVarScope->usScopeKind = SCOPEKIND_IN;
				pstVarScope->min = pVarScope->min;
				pstVarScope->max = typeScope.max;
			}
		} else {
			if (Tr_ValueEqual(&pVarScope->min, &typeScope.max)) {
				pstVarScope->usScopeKind = SCOPEKIND_VOID;
				Tr_ValueNewZero(&pstVarScope->min, pstVarScope->bFloat);
				Tr_ValueNewZero(&pstVarScope->max, pstVarScope->bFloat);
			} else if (Tr_ValueLessOrEqual(&variScope->max, &pVarScope->min)) {
				pstVarScope->usScopeKind = SCOPEKIND_IN;

				if (pstVarScope->bFloat) {
					pstVarScope->min = pVarScope->min;
				} else {
					Tr_ValueInc(&pVarScope->min, &pstVarScope->min);
				}
				pstVarScope->max = typeScope.max;
			} else if (Tr_ValueLessOrEqual(&variScope->min, &pVarScope->min)) {
				pstVarScope->usScopeKind = SCOPEKIND_IN;
				pstVarScope->min = variScope->max;
				pstVarScope->max = typeScope.max;
			} else {
				pstVarScope->usScopeKind = SCOPEKIND_IN;
				if (pstVarScope->bFloat) {
					pstVarScope->min = pVarScope->min;
				} else {
					Tr_ValueInc(&pVarScope->min, &pstVarScope->min);
				}
				pstVarScope->max = typeScope.max;
			}
		}
	} else {
		if (bEqual) {
			pstVarScope->usScopeKind = SCOPEKIND_OUT;
			pstVarScope->min = variScope->min;
			pstVarScope->max = variScope->max;
		} else {
			if (Tr_ValueEqual(&variScope->min, &typeScope.min)) {
				pstVarScope->usScopeKind = SCOPEKIND_IN;
				pstVarScope->min = variScope->max;
				pstVarScope->max = typeScope.max;
			} else {
				pstVarScope->usScopeKind = SCOPEKIND_IN;

				if (pstVarScope->bFloat) {
					pstVarScope->min = typeScope.min;
				} else {
					Tr_ValueInc(&typeScope.min, &pstVarScope->min);
				}
				pstVarScope->max = typeScope.max;
			}
		}
	}
	Tr_ScpAdjustByScp(pstVarScope, &storageScp);
}
VOID Tr_ScpLimitScopeByLess(TRVALUESCP *variScope, TRVALUESCP *pVarScope,
		TRVALUESCP *pstVarScope, BOOL bEqual) {
	TRVALUESCP typeScope;
	TRVALUESCP storageScp;
	if (variScope->usScopeKind == SCOPEKIND_VOID
			|| variScope->usScopeKind == SCOPEKIND_NAN) {
		return;
	}
	if (pVarScope->usScopeKind == SCOPEKIND_VOID
			|| pVarScope->usScopeKind == SCOPEKIND_NAN) {
		return;
	}
	Tr_ScpArithPromotionFlags(variScope, pVarScope, pstVarScope);
	Tr_ScpGetMinMaxByBytes(&typeScope, pstVarScope->size, pstVarScope->bSigned,
			pstVarScope->bFloat);
	Tr_ScpGetMinMaxByBytes(&storageScp, variScope->size, variScope->bSigned,
			variScope->bFloat);
	Tr_ScpAdjustByScp(variScope, &typeScope);
	Tr_ScpAdjustByScp(pVarScope, &typeScope);
	if (variScope->usScopeKind == SCOPEKIND_IN
			&& pVarScope->usScopeKind == SCOPEKIND_IN) {
		if (bEqual) {
			if (Tr_ValueLessThan(&pVarScope->max, &variScope->min)) {
				pstVarScope->usScopeKind = SCOPEKIND_VOID;
				Tr_ValueNewZero(&pstVarScope->min, pstVarScope->bFloat);
				Tr_ValueNewZero(&pstVarScope->max, pstVarScope->bFloat);
			} else if (Tr_ValueLessThan(&pVarScope->max, &variScope->max)) {
				pstVarScope->usScopeKind = SCOPEKIND_IN;
				pstVarScope->min = variScope->min;
				pstVarScope->max = pVarScope->max;
			} else {
				pstVarScope->usScopeKind = SCOPEKIND_IN;
				pstVarScope->min = variScope->min;
				pstVarScope->max = variScope->max;
			}
		} else {
			if (Tr_ValueLessOrEqual(&pVarScope->max, &variScope->min)) {
				pstVarScope->usScopeKind = SCOPEKIND_VOID;
				Tr_ValueNewZero(&pstVarScope->min, pstVarScope->bFloat);
				Tr_ValueNewZero(&pstVarScope->max, pstVarScope->bFloat);
			} else if (Tr_ValueLessOrEqual(&pVarScope->max, &variScope->max)) {
				pstVarScope->usScopeKind = SCOPEKIND_IN;

				if (pstVarScope->bFloat) {
					pstVarScope->max = pVarScope->max;
				} else {
					Tr_ValueDec(&pVarScope->max, &pstVarScope->max);
				}
				pstVarScope->min = variScope->min;
			} else {
				pstVarScope->usScopeKind = SCOPEKIND_IN;
				pstVarScope->min = variScope->min;
				pstVarScope->max = variScope->max;
			}
		}
	} else if (variScope->usScopeKind == SCOPEKIND_IN
			&& pVarScope->usScopeKind == SCOPEKIND_OUT) {
		if (bEqual) {
			pstVarScope->usScopeKind = SCOPEKIND_IN;
			pstVarScope->min = variScope->min;
			pstVarScope->max = variScope->max;
		} else {
			if (Tr_ValueEqual(&variScope->max, &typeScope.max)) {
				pstVarScope->usScopeKind = SCOPEKIND_IN;

				if (pstVarScope->bFloat) {
					pstVarScope->max = typeScope.max;
				} else {
					Tr_ValueDec(&typeScope.max, &pstVarScope->max);
				}
				pstVarScope->min = variScope->min;
			} else {
				pstVarScope->usScopeKind = SCOPEKIND_IN;
				pstVarScope->min = variScope->min;
				pstVarScope->max = variScope->max;
			}
		}
	} else if (variScope->usScopeKind == SCOPEKIND_OUT
			&& pVarScope->usScopeKind == SCOPEKIND_IN) {
		if (bEqual) {
			if (Tr_ValueEqual(&pVarScope->max, &typeScope.max)) {
				pstVarScope->usScopeKind = SCOPEKIND_OUT;
				pstVarScope->min = variScope->min;
				pstVarScope->max = variScope->max;
			} else if (Tr_ValueLessThan(&pVarScope->max, &variScope->min)) {
				pstVarScope->usScopeKind = SCOPEKIND_IN;
				pstVarScope->max = pVarScope->max;
				pstVarScope->min = typeScope.min;
			} else if (Tr_ValueLessThan(&pVarScope->max, &variScope->max)) {
				pstVarScope->usScopeKind = SCOPEKIND_IN;
				pstVarScope->max = variScope->min;
				pstVarScope->min = typeScope.min;
			} else {
				pstVarScope->usScopeKind = SCOPEKIND_IN;
				pstVarScope->max = pVarScope->max;
				pstVarScope->min = typeScope.min;
			}
		} else {
			if (Tr_ValueEqual(&pVarScope->max, &typeScope.min)) {
				pstVarScope->usScopeKind = SCOPEKIND_VOID;
				Tr_ValueNewZero(&pstVarScope->min, pstVarScope->bFloat);
				Tr_ValueNewZero(&pstVarScope->max, pstVarScope->bFloat);
			} else if (Tr_ValueLessOrEqual(&pVarScope->max, &variScope->min)) {
				pstVarScope->usScopeKind = SCOPEKIND_IN;
				if (pstVarScope->bFloat) {
					pstVarScope->max = pVarScope->max;
				} else {
					Tr_ValueDec(&pVarScope->max, &pstVarScope->max);
				}
				pstVarScope->min = typeScope.min;
			} else if (Tr_ValueLessOrEqual(&pVarScope->max, &variScope->max)) {
				pstVarScope->usScopeKind = SCOPEKIND_IN;
				pstVarScope->max = variScope->min;
				pstVarScope->min = typeScope.min;
			} else {
				pstVarScope->usScopeKind = SCOPEKIND_IN;
				if (pstVarScope->bFloat) {
					pstVarScope->max = pVarScope->max;
				} else {
					Tr_ValueDec(&pVarScope->max, &pstVarScope->max);
				}
				pstVarScope->min = typeScope.min;
			}
		}
	} else if (variScope->usScopeKind == SCOPEKIND_OUT
			&& pVarScope->usScopeKind == SCOPEKIND_OUT) {
		if (bEqual) {
			pstVarScope->usScopeKind = SCOPEKIND_OUT;
			pstVarScope->min = variScope->min;
			pstVarScope->max = variScope->max;
		} else {
			if (Tr_ValueEqual(&variScope->max, &typeScope.max)) {
				pstVarScope->usScopeKind = SCOPEKIND_IN;
				pstVarScope->max = variScope->min;
				pstVarScope->min = typeScope.min;
			} else {
				pstVarScope->usScopeKind = SCOPEKIND_IN;
				Tr_ValueDec(&typeScope.max, &pstVarScope->max);
				if (pstVarScope->bFloat) {
					pstVarScope->max = typeScope.max;
				} else {
					Tr_ValueDec(&typeScope.max, &pstVarScope->max);
				}
				pstVarScope->min = typeScope.min;
			}
		}
	}
	Tr_ScpAdjustByScp(pstVarScope, &storageScp);
}

VOID Tr_ScpSetInvalid(TRVALUESCP *stResult) {
	stResult->usScopeKind = SCOPEKIND_VOID;
	stResult->calError = 0;
}
